﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;

/*
 * 
 * This is a list of tags/key words that the user ight be interested in.
 * the arrayList contains all the tag entries.  Each tag entry is made up of 
 * the main tag and any related key words.  
 * 
 * 
 * */

namespace FeedsLibrary.Feeds
{
    public class TagList
    {
        private List<List<string>> _allTagsList;
        private Dictionary<string,int> _counts = new Dictionary<string, int>();

        public TagList( string tagFile )
        {
            _allTagsList = new List<List<string>>();

            if ( File.Exists( tagFile ) )
            {
                // Create an instance of StreamReader to read from a file.
                // The using statement also closes the StreamReader.
                using ( StreamReader sr = new StreamReader( tagFile ) )
                {
                    string line;
                    // Read and display lines from the file until the end of 
                    // the file is reached.
                    while ( ( line = sr.ReadLine() ) != null )
                    {
                        if ( !String.IsNullOrEmpty(line) && !line.StartsWith( @"##" ) )
                        {
                            List<string> completeList = new List<string>( line.Split( '|' ) );
                            List<string> modifiedTags = new List<string>();

                            //then add any with a & in them
                            foreach ( string s in completeList )
                            {
                                if ( s.Contains( "&" ) )
                                {
                                    modifiedTags.Add( s.Replace( "&", "and" ) );
                                    modifiedTags.Add( s.Replace( "&", "+" ) );
                                }
                            }

                            //any new ones added?
                            if ( modifiedTags.Count>0 )
                            {
                                completeList.AddRange( modifiedTags );
                            }
                            _allTagsList.Add( completeList );
                        }
                    }
                }
            }
        }

        public int SmallestValue()
        {
            int sm = 999;

            foreach ( string key in _counts.Keys )
            {
                Console.WriteLine( "Key " + key +" = " + _counts[key] );
            }
 
            foreach ( int i in _counts.Values )
            {
                if ( sm > i )
                {
                    sm = i;
                }
            }
            return sm;
        }

        public int LargestValue()
        {
            int result = 0;

            foreach ( int i in _counts.Values )
            {
                if ( result < i )
                {
                    result = i;
                }
            }
            return result;
        }

        public List<string> ParseTags( string newsItem )
        {
            //to lower case
            string tempstring = " " + newsItem.ToLower() + " ";

            //remove the HTML tags
            tempstring = Regex.Replace( tempstring, @"<[^>]*>", String.Empty );

            List<string> tagsToAdd = new List<string>();

            //go through all the different tag rows, ie, the main tags
            foreach ( List<string> oneSetOfTags in _allTagsList )
            {
                //did we find a tag?
                bool success = false;
                //should we ignore it?
                bool dontAdd = false;

                //go through all the child tags that contribute to the main tag
                foreach ( string oneTag in oneSetOfTags )
                {
                    bool cancelTag = false;
                    string tempTag = oneTag;

                    //is it a cancel tag?
                    if ( tempTag.StartsWith( "-" ) )
                    {
                        tempTag = tempTag.Remove( 0, 1 );
                        cancelTag = true;
                    }

                    //only check if a tag is actually set to something
                    if ( tempTag.Length > 0 )
                    {
                        Match m = CheckForTag( tempstring, tempTag );
                        //if it contains the sub tag
                        if ( m.Success && !cancelTag )
                        {
                            success = true;
                        }
                        else if ( m.Success && cancelTag )
                        {
                            dontAdd = true;
                        }
                    }
                }

                if ( success && ! dontAdd )
                {
                    string key = oneSetOfTags[ 0 ];
                    if ( _counts.ContainsKey( key ) )
                    {
                        int i = ( int )_counts[ key ];
                        _counts[ key ] = i + 1;
                    }
                    else
                    {
                        _counts.Add( key, 1 );
                    }

                    //then check for and add the main tag
                    if ( !tagsToAdd.Contains( oneSetOfTags[ 0 ] ) )
                    {
                        tagsToAdd.Add( oneSetOfTags[ 0 ] );
                        Console.WriteLine( "Added " + oneSetOfTags[ 0 ] );
                    }
                }
            }
            return tagsToAdd;
        }

        private static Match CheckForTag( string text, string tag )
        {
            string regEx = @"";
            string tempTag = tag;

            //is it a wildcard one?
            if ( tempTag.EndsWith( @"*" ) )
            {
                regEx = @"(|.*)\b" + regEx;
                tempTag = tempTag.Replace( @"*", @"" );
            }
            else
            {
                regEx = @"(|s|es|\.|\:|\;|\,|'s)\b";
            }

            string targetExpression = @"\b" + Regex.Escape( tempTag.ToLower() ) + regEx;
            return Regex.Match( text, targetExpression );
        }
    }
}